package com.darren.euc.dao;

import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

/**
 * Created by hc on 2016/11/16.
 */
@Component
public class CommonDao {

    @PersistenceContext(unitName = "euc")
    @Qualifier(value = "entityManagerFactory")
    private EntityManager entityManager;

    public Integer findBySqlGetTotalNum(String sql) {
        Query query = entityManager.createNativeQuery(sql);
        Object object = query.getSingleResult();
        return Integer.parseInt(object.toString());
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> findBySql(String sql, Class<T> clazz) {
        Query query = entityManager.createNativeQuery(sql, clazz);
        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> findBySqlPageable(String sql, Class<T> clazz, Pageable page) {
        Query query = entityManager.createNativeQuery(sql, clazz);
        query.setFirstResult(page.getPageNumber() * page.getPageSize());
        query.setMaxResults(page.getPageSize());
        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> findBySqlPageable(String sql, Pageable page) {
        Query query = entityManager.createNativeQuery(sql);
        query.setFirstResult(page.getPageNumber() * page.getPageSize());
        query.setMaxResults(page.getPageSize());
        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
	public <T> List<T> findByParameters(String hql, Class<T> clazz, List<Object> list) {
        Query query = entityManager.createQuery(hql);
        for (int i = 0; i < list.size(); i++) {
            query.setParameter(i, list.get(i));
        }
        return query.getResultList();
    }

    public <T> List<T> findByParameters(String hql, Class<T> clazz, Map<String, Object> parameters) {
        Query query = entityManager.createQuery(hql);
        for(Map.Entry<String,Object> entry : parameters.entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query.getResultList();
    }

    public <T> List<T> findByParameters(String hql, Map<String, Object> parameters) {
        Query query = entityManager.createQuery(hql);
        for(Map.Entry<String,Object> entry : parameters.entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query.getResultList();
    }


    @SuppressWarnings("unchecked")
	public <T> List<T> getResultPage(String hql, Map<String, Object> parameters, Pageable pageable) {
        Query query = this.createQuery(hql, pageable);
        for(Map.Entry<String,Object> entry : parameters.entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query.getResultList();
    }

    public long getCount(String hql, Map<String, Object> parameters) {
        Query query = this.entityManager.createQuery(this.countHql(hql));
        for(Map.Entry<String,Object> entry:parameters.entrySet()){
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return (Long) query.getSingleResult();
    }

    public Query createQuery(String hql, Pageable pageable){
        int pageSize = pageable.getPageSize();
        int currentPage = pageable.getPageNumber();
        int index = currentPage * pageSize;
        Query query = this.entityManager.createQuery(hql);
        query.setMaxResults(pageSize);
        query.setFirstResult(index);
        return query;
    }

    public String countHql(String hql) {
        if (hql.trim().toLowerCase().startsWith("from")) {
            return "select count(*) " + hql;
        } else {
            int fromIndex = hql.toLowerCase().indexOf("from");
            return "select count(*) " + hql.substring(fromIndex);
        }
    }

}
